 /*-----------------------------------------------File Info------------------------------------------------
** File Name:               uart user.h  
** Last modified date:      2016.09.8
** Last version:            V0.1
** Description:             
**
**--------------------------------------------------------------------------------------------------------            
** Created date:            2016.09.8
** author:                  YLY
** Version:                 V0.1
** Descriptions:            串口驱动
**--------------------------------------------------------------------------------------------------------*/

#include "bspUART.h"
#ifdef UART_DAM_EN
#include "bspDma.h"
#endif
tsUart tUart0,tUart1;

static void defaultUartCallback(uint8_t *pRxBuf, uint16_t size)
{
	;
}

#ifdef UART_DAM_EN
static void uart0DmaCallBack(teDmaCallBackSta eCb)
{
	usart_dma_transmit_config(USART0, USART_DENT_DISABLE);	
}

static void uart1DmaCallBack(teDmaCallBackSta eCb)
{
	usart_dma_transmit_config(USART1, USART_DENT_DISABLE);	
}


void uartDmaWrite(tsCfgUart *cfg, uint8_t *pRxBuf, uint16_t rxBufSize)
{	
	if(cfg->com == USART0)
	{
		usart_interrupt_flag_clear(USART0, USART_INT_FLAG_TC);
		if(dmaInit(UART0_WRITE_DMA_CHANNEL, DMA_WRITE, pRxBuf, USART0_TDATA_ADDRESS, rxBufSize, uart0DmaCallBack) == false)
		{
			return;
		}
		/* USART DMA enable for transmission */
		usart_dma_transmit_config(USART0, USART_DENT_ENABLE);			
	}
	else
	{
		usart_interrupt_flag_clear(USART1, USART_INT_FLAG_TC);
		if(dmaInit(UART1_WRITE_DMA_CHANNEL, DMA_WRITE, pRxBuf, USART1_TDATA_ADDRESS, rxBufSize, uart1DmaCallBack) == false)
		{
			return;
		}	
		/* USART DMA enable for transmission */
		usart_dma_transmit_config(USART1, USART_DENT_ENABLE);				
	}			
}
#endif	//UART_DAM_EN
/*!
    \brief      init Uart function
    \param[in]  cfg: USARTx(x = 0,1,2) 
    \param[in] 	baudRate: 2400,9600... 115200
    \param[in]  ePort: teUartPort	
    \param[in]  rxBufSize: 	0~65535 
	\param[in]  pCallBack:	UART Call Back Funce
    \retval     none
	
	GPIO_AF:参考 datasheet 2.6.7 GD32E230xx pin alternate functions
注意:uart1不支持超时定时器,串口成帧需要应用层自行实现
*/
void uartInit(tsCfgUart *cfg, uint32_t baudRate, 
			  uint8_t *pReceBuf, uint32_t rxBufSize, pUartCallBackFun pCallBack)
{ 	 
	uint32_t tout;
	
	gpioConfig(&cfg->rxIo);	
	gpioConfig(&cfg->txIo);	

	if(cfg->com == USART0)
	{
		tUart0.pRxBuf = pReceBuf;		
		tUart0.rxBufSize = rxBufSize;
		if(pCallBack)
			tUart0.pRxCb = pCallBack;
		else
			tUart0.pRxCb = defaultUartCallback;
	}
	else
	{
		tUart1.pRxBuf = pReceBuf;		
		tUart1.rxBufSize = rxBufSize;
		if(pCallBack)
			tUart1.pRxCb = pCallBack;
		else
			tUart1.pRxCb = defaultUartCallback;				
	}
	
	/* enable USART clock */
	rcu_periph_clock_enable(cfg->rcu);
	/* USART interrupt configuration */
	
#if BSP_MCU_TYPE == BSP_MCU_GD32E23x			
    nvic_irq_enable(cfg->nvicIrq, cfg->nvicIrqPriority);
#elif BSP_MCU_TYPE == BSP_MCU_GD32F3x0
	nvic_irq_enable(cfg->nvicIrq, cfg->nvicIrqPriority,cfg->nvicIrqSubPriority);	
#endif 	
	
	
	/* USART configure */
	usart_deinit(cfg->com);	
	
	usart_baudrate_set(cfg->com, baudRate);
#if BSP_MCU_TYPE != BSP_MCU_GD32F1x0
	usart_receive_fifo_enable(cfg->com);	//	FIFO
#endif
	/* enable the USART receive timeout and configure the time of timeout */
	tout = baudRate/200;	//5mS
	if(tout < 40)
		tout = 40;
	
	usart_receiver_timeout_enable(cfg->com);
	usart_receiver_timeout_threshold_config(cfg->com, tout);
	
	usart_receive_config(cfg->com, USART_RECEIVE_ENABLE);		//RX
	usart_transmit_config(cfg->com, USART_TRANSMIT_ENABLE);		//TX
	
	usart_interrupt_enable(cfg->com, USART_INT_RT);				//RX-TimerOut		
	usart_interrupt_enable(cfg->com, USART_INT_RBNE);			//RX-INT
	
	usart_enable(cfg->com);	
}

void uartDeinit(tsCfgUart *cfg)
{
	usart_deinit(cfg->com);	
}

/* 中断处理 */
void USART0_IRQHandler(void)
{
	uint8_t data;
	
	//--------------------------------接收-------------------------------------
	if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE) == SET)		/* 接收到数据 */
	{
		if(tUart0.pRxBuf == NULL)
		{
			data = usart_data_receive(USART0);//从FIFO读数据 		
			if(tUart0.pRxCb)
				tUart0.pRxCb(&data, 1);	//回调	
		}
		else
		{
			tUart0.pRxBuf[tUart0.rxCount++] = usart_data_receive(USART0);//从FIFO读数据 
			if(tUart0.rxCount == tUart0.rxBufSize)
			{
				if(tUart0.pRxCb)				
					tUart0.pRxCb(tUart0.pRxBuf, tUart0.rxCount);	//回调
				tUart0.rxCount = 0;	/* 清除计数 */						
			}
		}		
		usart_interrupt_flag_clear(USART0,USART_INT_FLAG_RBNE);	//清除接收中断		
	}
	
	if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_RT) == SET)
	{
		if(tUart0.pRxBuf != NULL)
		{
			if(tUart0.pRxCb)		
				tUart0.pRxCb(tUart0.pRxBuf, tUart0.rxCount);	//回调
		}
		tUart0.rxCount = 0;										/* 清除计数 */	
		usart_interrupt_flag_clear(USART0,USART_INT_FLAG_RT);	//清除超时中断	
	}	
	
	
	
	//-----------------------------发送----------------------------------------
	if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_TBE) == SET)
	{
		if(tUart0.pTxCb != NULL)
		{
			tUart0.pTxCb();
		}
		usart_interrupt_flag_clear(USART0,USART_INT_FLAG_TBE);	//清除超时中断	
	}	
		
	if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_TC) == SET)
	{	
		if(tUart0.pTxCb != NULL)
		{
			tUart0.pTxCb();
		}		
		usart_interrupt_flag_clear(USART0,USART_INT_FLAG_TC);	//清除超时中断	
	}	
}


/* 中断处理 */
void USART1_IRQHandler(void)
{
	uint8_t data;

	#if 0
	/* 处理接收中断  */
	if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE) == SET)		/* 接收到数据 */
	{		
		data = usart_data_receive(USART1);//从FIFO读数据 
		if(tUart1.pRxCb)
			tUart1.pRxCb(&data, 1);	//回调
		usart_interrupt_flag_clear(USART1,USART_INT_FLAG_RBNE);	//清除接收中断		
	}
	//UART1 无硬件接收超时中断
	#else
	if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE) == SET)		/* 接收到数据 */
	{
		if(tUart1.pRxBuf == NULL)
		{
			data = usart_data_receive(USART1);//从FIFO读数据 		
			if(tUart1.pRxCb)
				tUart1.pRxCb(&data, 1);	//回调	
		}
		else
		{
			tUart1.pRxBuf[tUart1.rxCount++] = usart_data_receive(USART1);//从FIFO读数据 
			if(tUart1.rxCount == tUart1.rxBufSize)
			{
				if(tUart1.pRxCb)				
					tUart1.pRxCb(tUart1.pRxBuf, tUart1.rxCount);	//回调
				tUart1.rxCount = 0;	/* 清除计数 */						
			}
		}		
		usart_interrupt_flag_clear(USART1,USART_INT_FLAG_RBNE);	//清除接收中断		
	}
	
	if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RT) == SET)
	{
		if(tUart1.pRxBuf != NULL)
		{
			if(tUart1.pRxCb)		
				tUart1.pRxCb(tUart1.pRxBuf, tUart1.rxCount);	//回调
		}
		tUart1.rxCount = 0;										/* 清除计数 */	
		usart_interrupt_flag_clear(USART1,USART_INT_FLAG_RT);	//清除超时中断	
	}
	#endif	
	
	//-----------------------------发送----------------------------------------
	if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_TBE) == SET)
	{
		if(tUart1.pTxCb != NULL)
		{
			tUart1.pTxCb();
		}
		usart_interrupt_flag_clear(USART1,USART_INT_FLAG_TBE);	//清除超时中断	
	}	
		
	if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_TC) == SET)
	{	
		if(tUart1.pTxCb != NULL)
		{
			tUart1.pTxCb();
		}		
		usart_interrupt_flag_clear(USART1,USART_INT_FLAG_TC);	//清除超时中断	
	}	
}

/*
* 阻塞发送
*/
void uartWrite(tsCfgUart *cfg, uint8_t *pRxBuf, uint16_t size)
{
	usart_interrupt_disable(cfg->com, USART_INT_TBE);	//关闭发送FIFO空		
	usart_interrupt_disable(cfg->com, USART_INT_TC);	//关闭数据发送完成	
	while(size --)
	{
		usart_data_transmit(cfg->com, *pRxBuf++);
		while(RESET == usart_flag_get(cfg->com, USART_FLAG_TBE));//等待发送寄存器空
	}
	while(RESET == usart_flag_get(cfg->com, USART_FLAG_TC));//等待数据发送完成	
}

/*
* 中断发送
*/
void uartIntWriteByte(tsCfgUart *cfg, uint8_t data, pUartWrIntCbFun cb)
{			
	usart_interrupt_disable(cfg->com, USART_INT_TC);	//关闭数据发送完成	
	if(cfg->com == USART0)
	{
		if(cb)
			tUart0.pTxCb = cb;
		else
			tUart0.pTxCb = NULL;
	}
	else
	{
		if(cb)
			tUart1.pTxCb = cb;
		else
			tUart1.pTxCb = NULL;				
	}
	usart_data_transmit(cfg->com, data);			
	usart_interrupt_enable(cfg->com, USART_INT_TC);					//数据发送完成				
}



void usartReadConfig(tsCfgUart *cfg, bool en)
{
	uint32_t rxconfig;
	
	if(en)
		rxconfig = USART_RECEIVE_ENABLE;
	else
		rxconfig = USART_RECEIVE_DISABLE;
	
	usart_receive_config(cfg->com,rxconfig);
}

void usartWriteConfig(tsCfgUart *cfg, bool en)
{
	uint32_t txconfig;
	
	if(en)
		txconfig = USART_TRANSMIT_ENABLE;
	else
		txconfig = USART_TRANSMIT_DISABLE;
	
	usart_transmit_config(cfg->com,txconfig);
}









